package com.henry.db.migrate.factory;

import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;

import com.henry.db.migrate.config.Config;
import com.henry.db.migrate.config.DbConfig;
import com.zaxxer.hikari.HikariDataSource;

public class DbFactory {

	private static Map<String, DataSource> dataSourceMap = new HashMap<>();

	/**
	 * 初始化数据源
	 *
	 * @return
	 */
	private synchronized static void initDataSource(String name) {
		if (!dataSourceMap.containsKey(name)) {
			DbConfig dbConfig = Config.getDbConfig(name);
			if (dbConfig.isPooled())
				dataSourceMap.put(name, initPooledDataSource(dbConfig));
			dataSourceMap.put(name, initUnpooledDataSource(dbConfig));
		}
	}

	/**
	 * 初始化mina非池化的数据源
	 *
	 * @param dbConfig
	 * @return
	 */
	private static UnpooledDataSource initUnpooledDataSource(DbConfig dbConfig) {
		return new UnpooledDataSource(dbConfig.getDriver(), dbConfig.getUrl(), dbConfig.getUsername(),
				dbConfig.getPassword());
	}

	/**
	 * 初始化数据库连接池
	 *
	 * @return
	 */
	private static DataSource initPooledDataSource(DbConfig dbConfig) {

		HikariDataSource ds = new HikariDataSource();
		ds.setDriverClassName(dbConfig.getDriver());
		ds.setJdbcUrl(dbConfig.getUrl());
		ds.setUsername(dbConfig.getUsername());
		ds.setPassword(dbConfig.getPassword());
		ds.setMaximumPoolSize(dbConfig.getPoolsize());
		return ds;
	}

	/**
	 * 返回该工程的数据源
	 *
	 * @return
	 */
	public static DataSource getDataSource(String name) {
		if (!dataSourceMap.containsKey(name))
			initDataSource(name);
		return dataSourceMap.get(name);
	}

	public static Connection getConnection(String name) {
		Connection connection = null;
		try {
			if (!dataSourceMap.containsKey(name))
				initDataSource(name);
			connection = dataSourceMap.get(name).getConnection();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("获取数据库连接失败");
		}
		return connection;
	}

	public static void close(Connection connection) {
		try {
			if (connection != null)
				connection.close();
		} catch (Exception e) {

		} finally {
			try {
				if (connection != null)
					connection.close();
			} catch (Exception e) {

			}
		}
	}

	public static void rollback(Connection connection) {
		try {
			if (connection != null)
				connection.rollback();
		} catch (Exception e) {

		} finally {
			try {
				if (connection != null)
					connection.rollback();
			} catch (Exception e) {

			}
		}
	}
}
